package com.zeus.hello;

import com.zeus.util.ActivitiUtil;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.springframework.util.FileCopyUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

/**
 * Created by Administrator on 2015/8/31.
 */
public class FirstFlow {
    ProcessEngine processEngine = ActivitiUtil.getProcessEngine();
    /**
     * 部署流程定义
     */
    @Test
    public void deploymentProcessDefinition(){
        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                //.name("流程定义")
                .addClasspathResource("diagrams/vacation.bpmn")
                //.addClasspathResource("diagrams/helloworld.bpmn")
                //.addClasspathResource("diagrams/helloworld.bpmn")
                .deploy();
        //System.out.println(processEngine);
        System.out.println("deploy ID:"+deployment.getId());
        System.out.println("deploy name:"+deployment.getName());
    }

    /**
     * 使用zip部署流程
     */
    @Test
    public void deploymentProcessDefinitionByZip(){
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);
        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                .name("流程定义")
                .addZipInputStream(zipInputStream)
                .deploy();
    }

    /**
     * 查询流程定义
     */
    @Test
    public void findProcessDefine(){
        List<ProcessDefinition> list = processEngine.getRepositoryService()
                .createProcessDefinitionQuery()
                .list();
        /**指定查询条件**/
        //.deploymentId()
        /**还可以指定排序*/
        //.orderByDeploymentId()
        /**指定结果集*/
        //.list()
        //.singleResult();
        for(ProcessDefinition p:list){
            System.out.println("ID:"+p.getId());
            System.out.println("KEY:"+p.getKey());
            System.out.println("Version:"+p.getVersion());
            System.out.println("Name:"+p.getName());
            System.out.println("Description:"+p.getDescription());
            System.out.println("#################################");
        }
    }
    /**
     * 删除流程定义
     */
    @Test
    public void deleteProcessDefinition(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
                .list();
        for (ProcessDefinition p:list){
            repositoryService.deleteDeployment(p.getDeploymentId(), true);
        }

    }

    /**
     * 获取资源中的图像
     */
    @Test
    public void getImageResource(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //repositoryService.getDeploymentResourceNames()
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
                .list();
        for (ProcessDefinition p:list){
            List<String> nameList = repositoryService.getDeploymentResourceNames(p.getDeploymentId());
            for(String name:nameList) {//System.out.println(name);
                InputStream inputStream = repositoryService.getResourceAsStream(p.getDeploymentId(), name);
                try {
                    FileCopyUtils.copy(inputStream,new FileOutputStream(new File("C:/test/"+name)));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取最新的流程定义版本
     */
    @Test
    public void getLastVersion(){
        List<ProcessDefinition> processDefinitionList =
                processEngine.getRepositoryService()
                        .createProcessDefinitionQuery()
                        .list();
        Map<String,ProcessDefinition> map = new LinkedHashMap<String, ProcessDefinition>();
        for(ProcessDefinition p:processDefinitionList){
            map.put(p.getKey(),p);
        }
        for(String key:map.keySet()){
            ProcessDefinition p = map.get(key);
            System.out.println("流程定义ID:"+p.getId());//流程定义的key+版本+随机数
            System.out.println("流程定义Name:"+p.getName());
            System.out.println("流程定义Key:"+key);
            System.out.println("流程定义version:"+p.getVersion());
            System.out.println("流程定义的资源文件bpmn:"+p.getResourceName());
            System.out.println("流程定义的图片文件PNG:"+p.getDiagramResourceName());
        }
    }

    /**
     * 删除所有的key的流程对象
     */
    @Test
    public void deleteProcessDefinitionByKey(){
        //（1）找到所有的流程定义对象
        //（2）从流程定义对象找到部署对象进行级联删除
    }

    /**
     * 下面是流程实例
     * 相关数据表
     * act_ru_execution执行对象表
     * act_hi_procinst 流程实例历史表
     * 一个流程中实例对象只有一个，但是执行对象可以有多个（如果流程中存在分支）
     * activiti用执行对象execute来描述执行过程中的每一个节点
     * act_ru_task只有在节点是userTask时该表中才有数据
     * act_hi_taskinst  userTask历史表
     * act_hi_actinst 所有活动节点的历史表
     */

    /**
     * 启动流程实例
     * 通过key来启动流程实例系统采用的是最新版本的流程定义
     */
    @Test
    public void startProcessInstance(){
        //以流程定义对象的key来启动ProcessInstance
        //（1）获取RuntimeService
        String processDefinitionKey = "helloworld";
        ProcessInstance processInstance = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefinitionKey);
        System.out.println("流程实例:"+processInstance);
    }

    /**
     * 获取当前个人任务
     * 查的表是act_ru_execution
     */
    @Test
    public void findMyPersonalTask(){
        String assignee = "dongge";
        List<Task> taskList = processEngine.getTaskService()
                .createTaskQuery()
                .taskAssignee(assignee)
                .list();
    }

    /**
     * 完成任务
     */
    @Test
    public  void completeMyPersonalTask(){
        String taskId = "302";
        processEngine.getTaskService()
                .complete(taskId);
        System.out.println("完成任务：任务ID:"+taskId);
    }

    /**
     * 查询流程是否结束
     * 流程实例ID在整个流程中都不会变化
     * 当流程结束后流程实例将会从act_ru_execution中删除
     */
    @Test
    public void isProcessEnd(){
        //查询流程实例对象
        //如果为NULL就说明该流程已经结束
    }

    /**
     *  查询历史任务
     */
    @Test
    public void findHistoryTask(){
        String taskassignee = "dongge";
        List<HistoricTaskInstance> list = processEngine.getHistoryService()
                .createHistoricTaskInstanceQuery()
                .taskAssignee(taskassignee)//查询某个用户的历史任务
                .list();
    }


    /**
     * 查询历史流程实例
     */
    @Test
    public void findHistoryProcessInstance(){
        List<HistoricProcessInstance> list = processEngine.getHistoryService()
                .createHistoricProcessInstanceQuery()
                .list();
    }


}
